Hi,大家好,昨天介紹了一些關於Router的基本用法,也解決了在實作時遇到的一些問題,不過在都已經解決掉的現在就讓我們繼續學習吧!
match在Router中第一位登場的是match!在每一個Route判斷到網址的路徑相符,要渲染該組件時都會將物件match給傳進該組件中,不如...我們直接來看看他吧XD
以下的範例會直接拿昨天的結果來改,所以如果還沒有昨天的程式碼,可以到我的GutHub上clone下來,不然在範例下方我也會附上該範例的GitHub程式碼!
目前我們的專案的src/Component資料夾內有幾個組件,分別是Title、Home、About和Main,以下讓我們修改About.jsx:
import React from "react"
import { Route, Link } from "react-router-dom"
class About extends React.Component {
render() {
//在Route將組件渲染時,會傳入match物件,在這裡把它印出來
console.log(this.props.match)
return (
<div>
<h2>關於我們選單</h2>
<ul>
{/*url是match的屬性之一,會回傳網址列的路徑*/}
<li><Link to={`${this.props.match.url}`}>理念介紹</Link></li>
<li><Link to={`${this.props.match.url}/his`}>歷史沿革</Link></li>
</ul>
{/*path也是match的屬性之一,會回傳透過哪個Route進入的path屬性*/}
<Route exact path={`${this.props.match.path}`} component={Introd} />
<Route path={`${this.props.match.path}/his`} component={His} />
</div>
)
}
}
//下方簡單建立兩個組件
class Introd extends React.Component {
render() {
return <p>這裡是理念介紹</p>
}
}
class His extends React.Component {
render() {
return <p>這裡是歷史沿革</p>
}
}
export { About }
結果會如下:
match會帶著Route的url、path、isExact、params這四個屬性傳入到組件的class中,上方的範例中使用了兩個屬性:
url:會返回目前網址列上的目錄。path:會返回由進入的Route中設定的path。Route就是url符合path才會進入不是嗎?怎麼會不一樣?這個和params有關,下方會提到時會說明這部分!isExact:這個雖然沒有用到,但是這個屬性會回傳url的路徑是否要完全符合path,也就是當初有沒有在Route設定exact。params傳入參數了!真的走到哪都會有參數可以傳XD,在Route內該怎麼傳呢!讓我們在修改一次About:
import React from "react"
import { Route, Link } from "react-router-dom"
class About extends React.Component {
render() {
return (
<div>
<h2>關於我們選單</h2>
<ul>
{/*這裡不變*/}
<li><Link to={`${this.props.match.url}/introd`}>理念介紹</Link></li>
<li><Link to={`${this.props.match.url}/his`}>歷史沿革</Link></li>
</ul>
{/*這裡在path後方的/後面加上”:type“接受參數*/}
<Route exact path={`${this.props.match.path}/:type`} component={AboutContent} />
</div>
)
}
}
//將剛剛的兩個組件合成一個AboutContent
class AboutContent extends React.Component {
render() {
//印出目前match的狀態
console.log(this.props.match)
let content
//從match的params將參數type取出來,判斷是歷史沿革還是理念介紹
if (this.props.match.params.type == "introd")
content = "這裡是理念介紹"
else
content = "這裡是歷史沿革"
//把判斷後的字放進<p>中回傳
return (<p>{content}</p>)
}
}
export { About }
雖然做法不同,但是結果還是一樣:
由上方例子可以知道兩件事情
Route的參數是藉由url的位置去對應的,像上方的Link指定的to為${this.props.match.url}/introd其實就是About/introd,而在Router中設定的path為${this.props.match.path}/:type也就是About/:type,因為:type對應到的位置剛好是About/後的目錄introd,所以該值就會被送進到:type中。
match的path和url:
在擁有參數的情況下,match中的path會在網址的目錄上維持變數名稱,而url則是直接顯示變數值,所以如果上方About中的AboutContent組件,還需要再藉由Route輸出其他組件內容的話,在該path中用${this.props.match.path}設定就會繼續把目前擁有的變數往下傳,但如果是${this.props.match.url}就不會在擁有之前帶進來的變數了。
另外在Link的to中,為了將變數的值傳到Route中對應到path,則是反過來使用${this.props.match.url}設定to的路徑,如果是用${this.props.match.path}的話,傳到該變數的就還是名稱,不是值。
需要注意的是如果要傳進參數,那參數的數量和目錄的數量要相等,不然就不會判斷符合,例如下方幾種例子:
<li><Link to={`${this.props.match.url}/his/strAA`}>歷史沿革</Link></li>
上方的Link在下方的Route是不會符合的:
<Route exact path={`${this.props.match.path}/:type`} component={AboutContent} />
當然,如果將上方Route的exact屬性拿掉就會符合。<li><Link to={`${this.props.match.url}/his`}>歷史沿革</Link></li>
上方的Link在下方的Route是不會符合的:
<Route exact path={`${this.props.match.path}/:type/:strA`} component={AboutContent} />
如果是Route的參數設的比Link的to還多,那不論Route有沒有加上exact都不會符合!可不要想會有undefined這種狀況出現XD以上是對match的一些用法,其實也只是介紹他裡面會擁有哪些資訊而已,比較不容易搞清楚的地方應該會是path和url的部分,如果有問題的話再麻煩留言告訴我!可以一起討論!
最後謝謝各位大大的觀看,如果文章中有任何問題再麻煩留言告訴我,小弟會在盡快補充或修正文章內容的,謝謝大家![]()
參考文章: